xolvio / meteor-rtd-example-project

A template project to use for creating a meteor app with unit and webdriver testing
91 stars 27 forks source link

Suggestions on how to import underscore? #9

Closed mockdeep closed 11 years ago

mockdeep commented 11 years ago

We're using underscore in our meteor code and it seems like a good thing to have as-is in the specs as well. Any suggestions for how best to organize for importing it?

Thanks for this project, by the way. It's been a huge help in setting up testing on our meteor project. Frustrating, though, that this heavy handed approach seems to be the best way to handle it yet. I've got a bunch more stubs I'll try to contribute back.

xolvio commented 11 years ago

You can place underscore.js test/lib directory, and include it the karma.conf as a dependency. That'll make it available to unit tests. For acceptance tests, you'd probably want to require the files since they're not loaded by karma (sadly).

You're welcome and I'd love nothing more than to see stubs that would help.

mockdeep commented 11 years ago

Cool, thanks. I'll do that then.

mockdeep commented 11 years ago

Still trekking through one error after another trying to get this up and running. Now I'm getting another error trying to get this thing to work Uncaught Error: Mismatched anonymous define() module: function ($) {. Any idea what to do about this? Full stack trace below. My karma.conf file has the following requires:

files = [ 
  MOCHA,
  MOCHA_ADAPTER,
  REQUIRE,
  REQUIRE_ADAPTER,
  'tests/lib/jquery-1.9.1.min.js',
  'tests/lib/underscore-min.js',
  'tests/stubs.js',

  'tests/**/*Spec.js',

  'client/**/*.js',
  'server/**/*.js',
  'shared/**/*.js'
];

Stack trace:

INFO [karma]: Karma server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 26.0 (Linux)]: Connected on socket id lLXbYOqKOZxJIuGD__ji
Chrome 26.0 (Linux) LOG: {}
Chrome 26.0 (Linux) LOG: {}
Chrome 26.0 (Linux): Executed 0 of 0 DISCONNECTED (25.223 secs / 0 secs)
WARN [Chrome 26.0 (Linux)]: Disconnected
INFO [Chrome 26.0 (Linux)]: Connected on socket id Q3yi1_0ugjSnE6lQ__jj
Chrome 26.0 (Linux) LOG: {}
Chrome 26.0 (Linux) LOG: {}
Chrome 26.0 (Linux) ERROR
    Uncaught Error: Mismatched anonymous define() module: function ($) {
      $.timeago = function(timestamp) {
        if (timestamp instanceof Date) {
          return inWords(timestamp);
        } else if (typeof timestamp === "string") {
          return inWords($.timeago.parse(timestamp));
        } else if (typeof timestamp === "number") {
          return inWords(new Date(timestamp));
        } else {
          return inWords($.timeago.datetime(timestamp));
        }
      };
      var $t = $.timeago;

      $.extend($.timeago, {
        settings: {
          refreshMillis: 60000,
          allowFuture: false,
          strings: {
            prefixAgo: null,
            prefixFromNow: null,
            suffixAgo: "ago",
            suffixFromNow: "from now",
            seconds: "less than a minute",
            minute: "about a minute",
            minutes: "%d minutes",
            hour: "about an hour",
            hours: "about %d hours",
            day: "a day",
            days: "%d days",
            month: "about a month",
            months: "%d months",
            year: "about a year",
            years: "%d years",
            wordSeparator: " ",
            numbers: []
          }
        },
        inWords: function(distanceMillis) {
          var $l = this.settings.strings;
          var prefix = $l.prefixAgo;
          var suffix = $l.suffixAgo;
          if (this.settings.allowFuture) {
            if (distanceMillis < 0) {
              prefix = $l.prefixFromNow;
              suffix = $l.suffixFromNow;
            }
          }

          var seconds = Math.abs(distanceMillis) / 1000;
          var minutes = seconds / 60;
          var hours = minutes / 60;
          var days = hours / 24;
          var years = days / 365;

          function substitute(stringOrFunction, number) {
            var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
            var value = ($l.numbers && $l.numbers[number]) || number;
            return string.replace(/%d/i, value);
          }

          var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
            seconds < 90 && substitute($l.minute, 1) ||
            minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
            minutes < 90 && substitute($l.hour, 1) ||
            hours < 24 && substitute($l.hours, Math.round(hours)) ||
            hours < 42 && substitute($l.day, 1) ||
            days < 30 && substitute($l.days, Math.round(days)) ||
            days < 45 && substitute($l.month, 1) ||
            days < 365 && substitute($l.months, Math.round(days / 30)) ||
            years < 1.5 && substitute($l.year, 1) ||
            substitute($l.years, Math.round(years));

          var separator = $l.wordSeparator || "";
          if ($l.wordSeparator === undefined) { separator = " "; }
          return $.trim([prefix, words, suffix].join(separator));
        },
        parse: function(iso8601) {
          var s = $.trim(iso8601);
          s = s.replace(/\.\d+/,""); // remove milliseconds
          s = s.replace(/-/,"/").replace(/-/,"/");
          s = s.replace(/T/," ").replace(/Z/," UTC");
          s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
          return new Date(s);
        },
        datetime: function(elem) {
          var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
          return $t.parse(iso8601);
        },
        isTime: function(elem) {
          // jQuery's `is()` doesn't play well with HTML5 in IE
          return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
        }
      });

      // functions that can be called via $(el).timeago('action')
      // init is default when no action is given
      // functions are called with context of a single element
      var functions = {
        init: function(){
          var refresh_el = $.proxy(refresh, this);
          refresh_el();
          var $s = $t.settings;
          if ($s.refreshMillis > 0) {
            setInterval(refresh_el, $s.refreshMillis);
          }
        },
        update: function(time){
          $(this).data('timeago', { datetime: $t.parse(time) });
          refresh.apply(this);
        }
      };

      $.fn.timeago = function(action, options) {
        var fn = action ? functions[action] : functions.init;
        if(!fn){
          throw new Error("Unknown function name '"+ action +"' for timeago");
        }
        // each over objects here and call the requested function
        this.each(function(){
          fn.call(this, options);
        });
        return this;
      };

      function refresh() {
        var data = prepareData(this);
        if (!isNaN(data.datetime)) {
          $(this).text(inWords(data.datetime));
        }
        return this;
      }

      function prepareData(element) {
        element = $(element);
        if (!element.data("timeago")) {
          element.data("timeago", { datetime: $t.datetime(element) });
          var text = $.trim(element.text());
          if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
            element.attr("title", text);
          }
        }
        return element.data("timeago");
      }

      function inWords(date) {
        return $t.inWords(distance(date));
      }

      function distance(date) {
        return (new Date().getTime() - date.getTime());
      }

      // fix for IE6 suckage
      document.createElement("abbr");
      document.createElement("time");
    }
    http://requirejs.org/docs/errors.html#mismatch
    at http://localhost:9876/adapter/lib/require.js?1365839185000:1746
mockdeep commented 11 years ago

nm, I apparently resolved it by removing the 2 REQUIRE_ lines from my karma.conf.

xolvio commented 11 years ago

I was about to say it's a require problem, but glad you found it